#include <set>

#include "tests.h"

TEST(set, ConstructorSet1) {
  s21::set<double> s21_empty_set;
  std::set<double> orig_empty_set;
  EXPECT_EQ(s21_empty_set.empty(), orig_empty_set.empty());
}

TEST(set, ConstructorSet2) {
  s21::set<float> s21_set = {};
  std::set<float> orig_set = {};
  auto s21_it = s21_set.begin();
  auto orig_it = orig_set.begin();
  EXPECT_EQ(s21_set.size(), orig_set.size());
  for (; s21_it != s21_set.end(); ++s21_it, ++orig_it) {
    EXPECT_TRUE(*orig_it == *s21_it);
  }
}

TEST(set, ConstructorSet3) {
  s21::set<char> s21_set = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
  std::set<char> orig_set = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
  auto s21_it = s21_set.begin();
  auto orig_it = orig_set.begin();
  EXPECT_EQ(s21_set.size(), orig_set.size());
  for (; s21_it != s21_set.end(); ++s21_it, ++orig_it) {
    EXPECT_TRUE(*orig_it == *s21_it);
  }
}

TEST(set, ConstructorCopy) {
  s21::set<int> s21_set = {1, 2, 3, 4, 5};
  std::set<int> orig_set = {1, 2, 3, 4, 5};
  s21::set<int> s21_set_copy = s21_set;
  std::set<int> orig_set_copy = orig_set;

  auto s21_it = s21_set_copy.begin();
  auto orig_it = orig_set_copy.begin();
  EXPECT_EQ(s21_set_copy.size(), orig_set_copy.size());
  for (; s21_it != s21_set_copy.end(); ++s21_it, ++orig_it) {
    EXPECT_TRUE(*orig_it == *s21_it);
  }
}

TEST(set, ConstructorMove) {
  s21::set<int> s21_set = {1, 2, 3, 4, 5};
  std::set<int> orig_set = {1, 2, 3, 4, 5};
  s21::set<int> s21_set_copy = std::move(s21_set);
  std::set<int> orig_set_copy = std::move(orig_set);
  EXPECT_EQ(s21_set.size(), orig_set.size());
  EXPECT_EQ(s21_set_copy.size(), orig_set_copy.size());
  auto s21_it = s21_set_copy.begin();
  auto orig_it = orig_set_copy.begin();
  for (; s21_it != s21_set_copy.end(); ++s21_it, ++orig_it) {
    EXPECT_TRUE(*orig_it == *s21_it);
  }
}

TEST(set, MoveAssignmentOperator) {
  s21::set<int> s21_set = {1, 2, 3, 4, 5};
  std::set<int> orig_set = {1, 2, 3, 4, 5};
  s21::set<int> s21_set_copy;
  std::set<int> orig_set_copy;
  s21_set_copy = std::move(s21_set);
  orig_set_copy = std::move(orig_set);
  EXPECT_EQ(s21_set.size(), orig_set.size());
  EXPECT_EQ(s21_set_copy.size(), orig_set_copy.size());
  auto s21_it = s21_set_copy.begin();
  auto orig_it = orig_set_copy.begin();
  for (; s21_it != s21_set_copy.end(); ++s21_it, ++orig_it) {
    EXPECT_TRUE(*orig_it == *s21_it);
  }
}

TEST(set, SetIterators) {
  s21::set<std::string> s21_set = {"We ", "are ", "the ", "champions!"};
  std::set<std::string> orig_set = {"We ", "are ", "the ", "champions!"};
  auto s21_it = s21_set.begin();
  auto orig_it = orig_set.begin();
  EXPECT_TRUE(*orig_it == *s21_it);
  s21_it = s21_set.begin();
  orig_it = orig_set.begin();
  s21_it++;
  orig_it++;
  --s21_it;
  --orig_it;
  EXPECT_TRUE(*orig_it == *s21_it);
}

TEST(set, Empty_Size) {
  s21::set<short> s21_empty_set;
  std::set<short> orig_empty_set;
  EXPECT_EQ(s21_empty_set.empty(), orig_empty_set.empty());
  EXPECT_EQ(s21_empty_set.size(), orig_empty_set.size());
  s21_empty_set.insert(2024);
  orig_empty_set.insert(2024);
  EXPECT_EQ(s21_empty_set.empty(), orig_empty_set.empty());
  EXPECT_EQ(s21_empty_set.size(), orig_empty_set.size());
}

TEST(set, Clear) {
  s21::set<char> s21_empty_set;
  std::set<char> orig_empty_set;
  EXPECT_EQ(s21_empty_set.empty(), orig_empty_set.empty());
  EXPECT_EQ(s21_empty_set.size(), orig_empty_set.size());
  s21_empty_set.insert('a');
  orig_empty_set.insert('b');
  EXPECT_EQ(s21_empty_set.empty(), orig_empty_set.empty());
  EXPECT_EQ(s21_empty_set.size(), orig_empty_set.size());
  s21_empty_set.clear();
  orig_empty_set.clear();
  EXPECT_EQ(s21_empty_set.empty(), orig_empty_set.empty());
  EXPECT_EQ(s21_empty_set.size(), orig_empty_set.size());
}

TEST(set, Insert) {
  s21::set<std::string> s21_set = {"We ", "are ", "the ", "champions!"};
  std::set<std::string> orig_set = {"We ", "are ", "the ", "champions!"};
  auto s21_it_bool = s21_set.insert(" Forever!\n");
  auto orig_it_bool = orig_set.insert(" Forever!\n");
  EXPECT_TRUE(s21_it_bool.second == orig_it_bool.second);
  EXPECT_TRUE(*s21_it_bool.first == *orig_it_bool.first);
  s21_it_bool = s21_set.insert(" See you soon!\n");
  orig_it_bool = orig_set.insert(" See you soon!\n");
  EXPECT_TRUE(s21_it_bool.second == orig_it_bool.second);
  EXPECT_TRUE(*s21_it_bool.first == *orig_it_bool.first);
}

TEST(set, Erase) {
  s21::set<int> s21_set = {5, 4, 3, 2, 7, 8, 9};
  std::set<int> orig_set = {5, 4, 3, 2, 7, 8, 9};
  auto size = s21_set.size();
  s21_set.erase(s21_set.end());
  auto new_size = s21_set.size();
  EXPECT_EQ(size, new_size);
  s21_set.erase(s21_set.begin());
  orig_set.erase(orig_set.begin());
  auto s21_it = s21_set.begin();
  auto orig_it = orig_set.begin();
  for (; s21_it != s21_set.end(); ++s21_it, ++orig_it) {
    EXPECT_TRUE(*orig_it == *s21_it);
  }
}

TEST(set, Swap) {
  s21::set<int> s21_set = {1};
  s21::set<int> s21_swap_set = {3, 4, 5};

  s21_set.swap(s21_swap_set);
  EXPECT_EQ(s21_set.size(), 3);
  EXPECT_EQ(s21_swap_set.size(), 1);
  EXPECT_EQ(*s21_set.begin(), 3);
  EXPECT_EQ(*s21_swap_set.begin(), 1);
}

TEST(set, SizeMaxSize) {
  s21::set<int> s{3, 5, 1, 4, 2};
  std::set<int> s1{3, 5, 1, 4, 2};
  ASSERT_EQ(s.size(), 5);
  ASSERT_GE(s.max_size(), s1.max_size());
  s.clear();
  ASSERT_EQ(s.size(), 0);
}

TEST(set, Merge) {
  s21::set<int> s21_set = {1, 10, 100, 1000, 10000};
  s21::set<int> s21_merge_set = {1000, 10000, 100000, 1000000, 10000000};
  s21_set.merge(s21_merge_set);

  std::set<int> orig_set = {1, 10, 100, 1000, 10000};
  std::set<int> orig_merge_set = {1000, 10000, 100000, 1000000, 10000000};
  orig_set.merge(orig_merge_set);
  auto s21_it = s21_set.begin();
  auto orig_it = orig_set.begin();
  for (; s21_it != s21_set.end(); ++s21_it, ++orig_it) {
    EXPECT_TRUE(*orig_it == *s21_it);
  }
  EXPECT_EQ(orig_set.size(), s21_set.size());
  EXPECT_EQ(s21_merge_set.size(), orig_merge_set.size());
}

TEST(set, Find) {
  s21::set<double> s21_set = {21,        21.21,  2121.21,   212121.21,
                              2121.2121, -21.21, -2121.2121};
  s21::set<double> orig_set = {21,        21.21,  2121.21,   212121.21,
                               2121.2121, -21.21, -2121.2121};
  auto s21_it = s21_set.find(21.21);
  auto orig_it = orig_set.find(21.21);
  EXPECT_TRUE(*orig_it == *s21_it);
}

TEST(set, ContainsSet) {
  s21::set<double> s21_set = {21,        21.21,  2121.21,   212121.21,
                              2121.2121, -21.21, -2121.2121};
  s21::set<double> orig_set = {21,        21.21,  2121.21,   212121.21,
                               2121.2121, -21.21, -2121.2121};
  EXPECT_EQ(s21_set.contains(12.12), orig_set.contains(12.12));
  EXPECT_EQ(s21_set.contains(21.21), orig_set.contains(21.21));
}

TEST(set, InsertMany) {
  std::set<int> orig_set = {1, 100, 1000, 10000};
  s21::set<int> s21_set = {1, 100, 1000, 10000};
  orig_set.insert(1);
  orig_set.insert(10);
  orig_set.insert(100000);
  orig_set.insert(-1000000);
  s21_set.insert_many(1, 10, 100000, -1000000);
  auto s21_it = s21_set.begin();
  auto orig_it = orig_set.begin();
  for (; s21_it != s21_set.end(); ++s21_it, ++orig_it) {
    EXPECT_EQ(*s21_it, *orig_it);
  }
}
